package com.niezhiliang.netty.websocket.spring.boot.demo.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.xml.crypto.Data;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

@Service
public class UdpServer {

    private static final int PORT = 10000; // UDP服务监听的端口号

    private static DatagramSocket receiveSocket;

    private static InetAddress receiveInetAddress;

    private static ConcurrentMap<String, DatagramPacket> datagramPacketPool =  new ConcurrentHashMap<>();

    private static int receivePort;
    // 将字节数组转换为16进制字符串
    private static String bytesToHex(byte[] bytes, int length) {
        StringBuffer hexString = new StringBuffer(2 * length);

        for (int i = 0; i < length; i++) {
            String hex = Integer.toHexString(0xff & bytes[i]);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }

    //解析16进制字段
    private static String parseHexStr(byte[] dataBytes) {
        // 解析字段
        int senderId = dataBytes[0] & 0xFF;
        int dataLength = dataBytes[1] & 0xFF;
        int deviceId = dataBytes[2] & 0xFF;
        byte[] zigbeeMacAddress = Arrays.copyOfRange(dataBytes, 3, 7);
        int modbusFunctionCode = dataBytes[7] & 0xFF;
        int stationId = dataBytes[8] & 0xFF;
        int modbusWriteFunctionCode = dataBytes[9] & 0xFF;
        byte[] registerAddress = Arrays.copyOfRange(dataBytes, 10, 12);
        byte[] functionCommand = Arrays.copyOfRange(dataBytes, 12, 14);
        System.out.println("Sender ID: " + Integer.toHexString(senderId));
        System.out.println("Data Length: " + Integer.toHexString(dataLength));
        System.out.println("Device ID: " + Integer.toHexString(deviceId));
        System.out.println("Zigbee MAC Address: " + bytesToHex(zigbeeMacAddress,zigbeeMacAddress.length));
        System.out.println("Modbus Function Code: " + Integer.toHexString(modbusFunctionCode));
        System.out.println("Station ID: " + stationId);
        System.out.println("Modbus Write Function Code: " + modbusWriteFunctionCode);
        System.out.println("Register Address: " + bytesToHex(registerAddress,registerAddress.length));
        System.out.println("Function Command: " + bytesToHex(functionCommand,functionCommand.length));

        String equipment =  Integer.toHexString(deviceId);
        if (equipment.equals("35")){
            equipment = "设备:岔道";
        }
        String macAddress = "MAC地址: " + bytesToHex(zigbeeMacAddress,zigbeeMacAddress.length);

        String register = bytesToHex(registerAddress,registerAddress.length);

        String command = bytesToHex(functionCommand,functionCommand.length);

        String action = register + command;

        if (register.equals("11f4") && command.equals("0001")) {
            action = "搬动道岔";
        }

        if (register.equals("11f5")){
            if (command.equals("0001")) {
                action = "岔位显示器左";
            }
            if (command.equals("0002")) {
                action = "岔位显示器右";
            }
            if (command.equals("0003")) {
                action = "岔位显示器故障";
            }
        }
        String result = "";
        result = equipment + "\n" +macAddress + "\n" + action + "\n";
        return result;

    }


    public static  void startUdpServer() {
        try (DatagramSocket socket = new DatagramSocket(PORT)) {
            byte[] receiveData = new byte[1024];
            receiveSocket = socket;
            while (true) {
                DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                socket.receive(receivePacket);
                String parseRes = parseHexStr(receivePacket.getData());
                String receivedHexMessage = bytesToHex(receivePacket.getData(), receivePacket.getLength());
                System.out.println("Received message: " + receivedHexMessage);


                // 在这里处理接收到的消息，比如进行业务逻辑处理
                int onlineNum = SocketServer.getOnlineNum();
                if (onlineNum > 0) {
//                    SocketServer.sendAll(receivedHexMessage);
                    SocketServer. sendAll(parseRes);
                }

                receiveInetAddress = receivePacket.getAddress();

                receivePort = receivePacket.getPort();

                // 发送响应
                String responseMessage = "Hello, Client!";
                byte[] responseData = responseMessage.getBytes();
                DatagramPacket responsePacket = new DatagramPacket(responseData, responseData.length, receivePacket.getAddress(), receivePacket.getPort());

                socket.send(responsePacket);

                //将接受的udp 包中的地址端口信息记录下来，后期可以放入缓存中
                DatagramPacket dump = new DatagramPacket(new byte[1],1,receivePacket.getAddress(),receivePacket.getPort());
                String key = dump.getAddress().getHostAddress()+receivePacket.getPort();
                if (datagramPacketPool.get(key)==null){
                    datagramPacketPool.put(key,dump);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static void sendToUDP(String message, InetAddress receiveAddr,int receivePort) {
        try {
            byte[] sendData = message.getBytes();
            DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, receiveAddr, receivePort);
            receiveSocket.send(sendPacket);
            System.out.println("Sent message to UDP server: " + message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 广播给所有 udp server
     *
     * */
    public static void sendBroadcastUnsafeToUDP(String message) {
        try {
            byte[] sendData = message.getBytes();
            //DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, receiveInetAddress, receivePort);
            if (receiveSocket==null||receiveSocket.isClosed()){
                System.out.println("udp server is over");
                return;
            }
            for (String key:datagramPacketPool.keySet()){
                DatagramPacket emit = datagramPacketPool.get(key);
                emit.setData(sendData);
                receiveSocket.send(emit);
                System.out.println("----------Sent message to UDP server: " + message);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

